/*
 * Copyright (C) 2011 JiangHongTiao
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */
package sk.lieskove.jianghongtiao.paris.helperutils.statistics;

import com.google.code.bing.search.client.BingSearchClient;
import com.google.code.bing.search.client.BingSearchServiceClientFactory;
import com.google.code.bing.search.schema.AdultOption;
import com.google.code.bing.search.schema.SearchOption;
import com.google.code.bing.search.schema.SearchResponse;
import com.google.code.bing.search.schema.SourceType;
import com.google.code.bing.search.schema.web.WebSearchOption;
import com.jellymold.boss.WebSearch.WebSearchFilter;
import org.apache.commons.io.FileUtils;
import org.apache.log4j.Logger;
import sk.lieskove.jianghongtiao.common.exceptions.HTTPResponseException;
import sk.lieskove.jianghongtiao.common.exceptions.InvalidPropertiesSettingsException;
import sk.lieskove.jianghongtiao.common.utils.PropertiesUtils;
import sk.lieskove.jianghongtiao.websearch.api.google.search.GWSLanguage;
import sk.lieskove.jianghongtiao.websearch.api.google.search.GoogleWebSearch;
import sk.lieskove.jianghongtiao.websearch.api.google.search.GoogleWebSearchImpl;

import java.io.File;
import java.io.IOException;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.logging.Level;

/**
 *
 * @author xjuraj
 */
public class DocumentTypeStatistics {

    private static String bingAppId = null;
    private static BingSearchClient bingSearch = null;
    private static com.jellymold.boss.WebSearch yahooSearch = null;
    private static GoogleWebSearch googleWebSearch = new GoogleWebSearchImpl();
    private static PropertiesUtils pu = new PropertiesUtils(DocumentTypeStatistics.class);
    private static Logger log = Logger.getLogger(DocumentTypeStatistics.class);
    private static Boolean googleAllowed;
    private static Boolean yahooAllowed;
    private static Boolean bingAllowed;

    /**
     * @param args the command line arguments
     */
    public static void main(String[] args) throws InvalidPropertiesSettingsException {
        init();
        String query = "";
        List extensions = null;
        try {
            extensions = FileUtils.readLines(new File("resources/fileExtensions"), "UTF-8");
        } catch (IOException ex) {
            java.util.logging.Logger.getLogger(DocumentTypeStatistics.class.getName()).log(Level.SEVERE, null, ex);
        }
        if (googleAllowed) {
            googleSearch("a");
        }
        if (yahooAllowed) {
            yahooSearch("a");
        }
        if (bingAllowed) {
            bingSearch("a");
        }
        System.out.print("Extension:");
        if (googleAllowed) {
            System.out.print("\tGoogle:");
        }
        if (yahooAllowed) {
            System.out.print("\tYahoo:");
        }
        if (bingAllowed) {
            System.out.print("\tBing:");
        }
        System.out.println();
        for (int i = 0; i < extensions.size(); i++) {
            query = "filetype:" + extensions.get(i);
            System.out.print(extensions.get(i));
            if (googleAllowed) {
                System.out.print("\t" + googleSearch(query));
            }
            if (yahooAllowed) {
                System.out.print("\t" + yahooSearch(query));
            }
            if (bingAllowed) {
                System.out.print("\t" + bingSearch(query));
            }
            System.out.println();
        }


    }

    private static void init() throws InvalidPropertiesSettingsException {
        googleAllowed = Boolean.valueOf(pu.getProperty(
                "google-search-enabled"));
        yahooAllowed = Boolean.valueOf(pu.getProperty(
                "yahoo-search-enabled"));
        bingAllowed = Boolean.valueOf(pu.getProperty(
                "bing-search-enabled"));
        if (googleAllowed) {
            createGoogleSearch();
        }
        if (yahooAllowed) {
            createYahooSearch();
        }
        if (bingAllowed) {
            createBingSearch();
        }

    }

    private static void createBingSearch() throws InvalidPropertiesSettingsException {
        BingSearchServiceClientFactory factory = BingSearchServiceClientFactory.newInstance();
        bingSearch = factory.createBingSearchClient();
        bingAppId = pu.getProperty("bing-service-api-key", null);
        if (bingAppId == null) {
            log.error(
                    "Bing AppId was not found in settings files. For more "
                    + "information visit url: http://www.bing.com/developers/createapp.aspx");
            throw new InvalidPropertiesSettingsException("bing-service-api-key",
                    DocumentTypeStatistics.class, "");
        }
    }

    private static void createGoogleSearch() throws InvalidPropertiesSettingsException {
        String appKey = pu.getProperty("google-search-api-key", null);
        if (appKey == null) {
            log.error(
                    "Google search API key was not found in settings files. For more "
                    + "information visit url: http://code.google.com/apis/loader/signup.html");
            throw new InvalidPropertiesSettingsException("google-search-api-key",
                    DocumentTypeStatistics.class, "");
        }
        googleWebSearch.withKey(appKey);
    }

    private static void createYahooSearch() throws InvalidPropertiesSettingsException {
        String yahooAppKey = pu.getProperty("yahoo-api-customer-key", null);
        if (yahooAppKey == null) {
            log.error(
                    "Yahoo customer key key was not found in settings files. For more "
                    + "information visit url: https://developer.apps.yahoo.com/dashboard/createKey.html");
            throw new InvalidPropertiesSettingsException(
                    "yahoo-api-customer-key", DocumentTypeStatistics.class, "");
        }
        yahooSearch = new com.jellymold.boss.WebSearch();
        yahooSearch.setAppKey(yahooAppKey);
    }

    public static Long googleSearch(String query) {
        GWSLanguage lang = GWSLanguage.fromCode(pu.getProperty(
                "google-search-language"));
        if (lang != null) {
            googleWebSearch.withLanguage(lang);
        }

        googleWebSearch.withQuery(query);
        try {
            String estimated = googleWebSearch.search(1).getResponseData().getCursor().getEstimatedResultCount();
            return Long.parseLong(estimated);
        } catch (HTTPResponseException e) {
            log.warn("Search through google failed!");
        }
        return 0L;
    }

    public static Long yahooSearch(String query) {
        Set<WebSearchFilter> filter = new HashSet<WebSearchFilter>();
        filter.add(WebSearchFilter.PORN);
        yahooSearch.setFilters(filter);
        yahooSearch.search(query);
        return yahooSearch.getTotalResults();
    }

    public static Long bingSearch(String query) {
        BingSearchClient.SearchRequestBuilder builder = bingSearch.newSearchRequestBuilder();
        builder.withAppId(bingAppId);
        builder.withQuery(query);
        builder.withSourceType(SourceType.WEB);
        builder.withVersion("2.0");
        builder.withMarket(pu.getProperty("bing-search-language"));
        builder.withAdultOption(AdultOption.MODERATE);
        builder.withSearchOption(SearchOption.ENABLE_HIGHLIGHTING);

        builder.withWebRequestOffset(0L);
        builder.withWebRequestSearchOption(
                WebSearchOption.DISABLE_HOST_COLLAPSING);
        builder.withWebRequestSearchOption(
                WebSearchOption.DISABLE_QUERY_ALTERATIONS);

        SearchResponse response = bingSearch.search(builder.getResult());
        return response.getWeb().getTotal();
    }
}
